import { NextAuthOptions } from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'
import { PrismaAdapter } from '@next-auth/prisma-adapter'
import prisma from './prisma'
import { compare } from 'bcryptjs'

export const authOptions: NextAuthOptions = {
  adapter: PrismaAdapter(prisma),
  session: {
    strategy: 'jwt',
    maxAge: 4 * 60 * 60, // 缩短为4小时
    updateAge: 30 * 60, // 30分钟更新一次会话
  },
  pages: {
    signIn: '/login',
    signOut: '/login?loggedOut=true',
    error: '/login',
  },
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        email: { label: '邮箱', type: 'email' },
        password: { label: '密码', type: 'password' },
        remember: { label: '记住登录', type: 'checkbox' },
      },
      async authorize(credentials) {
        console.log('开始认证用户...')
        
        try {
          if (!credentials?.email || !credentials?.password) {
            console.log('认证错误: 邮箱或密码为空')
            throw new Error('请输入邮箱和密码')
          }

          const user = await prisma.user.findUnique({
            where: {
              email: credentials.email,
            },
          })

          console.log('用户查询结果:', user ? '用户存在' : '用户不存在')

          if (!user) {
            throw new Error('用户不存在')
          }

          const isPasswordValid = await compare(credentials.password, user.password)
          
          console.log('密码验证结果:', isPasswordValid ? '有效' : '无效')

          if (!isPasswordValid) {
            throw new Error('密码错误')
          }

          console.log('认证成功, 用户角色:', user.role)
          
          return {
            id: user.id,
            email: user.email,
            name: user.name,
            role: user.role,
            remember: credentials.remember === 'true' || true,
          }
        } catch (err) {
          console.error('认证过程中的错误:', err)
          throw err
        }
      },
    }),
  ],
  callbacks: {
    async session({ session, token }) {
      if (token && session.user) {
        session.user.id = token.id as string
        session.user.role = token.role as string
        
        // 将lastActivity从token传递到session
        session.lastActivity = token.lastActivity || Date.now()
        
        // 设置session的过期时间
        if (token.remember) {
          // 30天
          session.maxAge = 30 * 24 * 60 * 60
        } else {
          // 4小时
          session.maxAge = 4 * 60 * 60
        }
      }
      return session
    },
    async jwt({ token, user, trigger }) {
      if (user) {
        token.id = user.id
        token.role = user.role
        token.remember = user.remember || false
        token.lastActivity = Date.now()
      }
      
      // 如果是会话更新，重置最后活动时间
      if (trigger === 'update') {
        token.lastActivity = Date.now()
      }
      
      return token
    },
    async signIn({ user, account, profile}) {
      // 记录登录时间
      user.loginTime = Date.now();
      return true;
    },
    async redirect({ url, baseUrl }) {
      const loginUrl = `${baseUrl}/login`;
      const homeUrl = `${baseUrl}/`; // 默认登录成功后的跳转地址

      console.log(`[AUTH] redirect: Original URL from NextAuth: "${url}"`);
      console.log(`[AUTH] redirect: Base URL: "${baseUrl}"`);

      // 检查 URL 是否是 signOut 页面配置的 URL
      const signOutUrlIsLoginWithParam = authOptions.pages?.signOut?.startsWith(loginUrl) && authOptions.pages?.signOut?.includes('loggedOut=true');
      
      // 1. 如果是明确的注销流程 (url 指向 pages.signOut 或包含 /logout)
      if (url === authOptions.pages?.signOut || url.includes('/logout') || (signOutUrlIsLoginWithParam && url.startsWith(loginUrl) && url.includes('loggedOut=true'))) {
        // 确保注销后总是返回到登录页，并带上时间戳和 loggedOut=true
        let targetLogoutUrl = `${baseUrl}/login?loggedOut=true`;
        if (!url.includes('t=')) { // 避免重复添加时间戳
          targetLogoutUrl += `&t=${Date.now()}`;
        }
        console.log(`[AUTH] redirect: Detected signOut flow. Redirecting to: "${targetLogoutUrl}"`);
        return targetLogoutUrl;
      }

      // 2. 如果 url 是登录页本身，并且不包含错误或注销参数，
      //    这通常意味着登录成功，并且没有特定的 callbackUrl，或者 callbackUrl 指向了登录页。
      //    此时，我们应该重定向到应用的主页或仪表盘。
      if (url.startsWith(loginUrl) && !url.includes('error=') && !url.includes('loggedOut=true')) {
        console.log(`[AUTH] redirect: Login successful, redirecting from tentative login URL ("${url}") to home: "${homeUrl}"`);
        return homeUrl;
      }

      // 3. 如果 url 是一个有效的 callbackUrl (不是登录页，也不是注销页)
      //    这种情况通常发生在用户尝试访问受保护页面被重定向到登录，登录后应返回该页面。
      //    或者是 signIn({... callbackUrl: '/some-page'}) 指定了回调。
      if (url.startsWith(baseUrl) && !url.startsWith(loginUrl)) {
        console.log(`[AUTH] redirect: Valid callbackUrl or internal redirect. Returning: "${url}"`);
        return url;
      }
      
      // 4. 其他所有情况，例如初始登录且没有 callbackUrl，也应重定向到首页
      //    或者如果 url 不是以 baseUrl 开头的外部地址，通常也应视为登录成功后去首页。
      console.log(`[AUTH] redirect: Defaulting to home for URL: "${url}"`);
      return homeUrl;
    },
  },
  cookies: {
    sessionToken: {
      name: `next-auth.session-token`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        maxAge: 4 * 60 * 60, // 默认4小时有效期
      },
    },
    callbackUrl: {
      name: `next-auth.callback-url`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        maxAge: 5 * 60, // 回调URL只有5分钟有效期
      },
    },
    csrfToken: {
      name: `next-auth.csrf-token`,
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production',
        maxAge: 2 * 60 * 60, // CSRF令牌2小时有效期
      },
    },
  },
  debug: process.env.NODE_ENV === 'development',
  secret: process.env.NEXTAUTH_SECRET || 'your-secret-key',
  events: {
    async signIn({ user, account, profile, isNewUser }) {
      console.log('用户登录事件触发，是否记住登录:', user.remember);
    },
    async session({ session, token }) {
      if (token.remember) {
        console.log('用户选择记住登录，设置30天会话');
        session.maxAge = 30 * 24 * 60 * 60;
      } else {
        console.log('用户未选择记住登录，设置4小时会话');
        session.maxAge = 4 * 60 * 60;
      }
    },
    async signOut({ session, token }) {
      console.log('用户注销事件触发，正在清理会话数据');
      try {
        // 如果使用了数据库会话，可以在这里执行额外的清理
        if (session?.user?.id) {
          console.log('正在清理用户ID相关的会话:', session.user.id);
          // 尝试删除数据库中的会话
          try {
            await prisma.session.deleteMany({
              where: {
                userId: session.user.id
              }
            });
            console.log('成功从数据库删除会话');
          } catch (dbError) {
            console.error('从数据库删除会话时出错:', dbError);
          }
        }
      } catch (error) {
        console.error('注销事件处理错误:', error);
      }
    },
  },
}

declare module 'next-auth' {
  interface Session {
    user: {
      id: string
      email: string
      name?: string | null
      role: string
    }
    lastActivity?: number
    maxAge?: number
  }

  interface User {
    id: string
    email: string
    name?: string | null
    role: string
    remember?: boolean
    loginTime?: number
  }
}

// JWT令牌扩展
declare module 'next-auth/jwt' {
  interface JWT {
    id: string
    role: string
    remember?: boolean
    lastActivity?: number
  }
} 